package com.dplus.common.utils.util;

import java.io.File;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import javax.validation.constraints.Digits.List;

import org.apache.commons.io.FileUtils;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

/**
 * RestTemplate 客户端请求工具
 * 
 * @ClassName: RestClientUtil
 * @Description: TODO(这里用一句话描述这个类的作用)
 * @author jacking
 * @date 2017年11月22日 下午12:40:38
 *
 */
public class RestClientUtil {
	public static RestTemplate restTemplate;

	public static RestClientUtil restClient = null;

	private RestClientUtil() {
		SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
//		requestFactory.setBufferRequestBody(false);
		restTemplate = new RestTemplate(requestFactory);
		restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
	}

	public Object getRestData(String requesturl, Class responseClz) {
		ResponseEntity<String> result = restTemplate.getForEntity(requesturl, String.class);
		String responseContent = result.getBody();
		if (responseClz != null
				&& (responseClz.getName().equals(Map.class.getName())
						|| responseClz.getName().equals(HashMap.class.getName()))
				|| responseClz.getName().equals(JSONObject.class.getName())) {
			System.out.println(responseContent);
			return JSON.parseObject(responseContent);
		} else {
			return responseContent;
		}

	}

	public static synchronized RestClientUtil getInstace() {
		if (restClient != null) {
			return restClient;
		} else {
			return new RestClientUtil();
		}

	}

	public Object getRestData(String requesturl, Class responseClz, Map uriVariables) {
		String result = restTemplate.getForObject(requesturl, String.class, uriVariables);
		if (responseClz != null
				&& (responseClz.getName().equals(Map.class.getName())
						|| responseClz.getName().equals(HashMap.class.getName()))
				|| responseClz.getName().equals(JSONObject.class.getName())) {
			return JSON.parseObject(result);
		} else {
			return result;
		}

	}

	public Object getRestData(String requesturl, Class responseClz, Object... uriVariables) {
		String result = restTemplate.getForObject(requesturl, String.class, uriVariables);
		if (responseClz != null
				&& (responseClz.getName().equals(Map.class.getName())
						|| responseClz.getName().equals(HashMap.class.getName()))
				|| responseClz.getName().equals(JSONObject.class.getName())) {
			return JSON.parseObject(result);
		} else {
			return result;
		}

	}

	public Object getRestDataByEntity(String requesturl, Class responseClz) {
		Object o = restTemplate.getForObject(requesturl, responseClz);
		return o;
	}

	public String postRestDataSave(String requesturl) {
		return restTemplate.postForObject(requesturl, null, String.class);
	}

	public String postRestDataSave(String requesturl, Map uriVariables) {
		// return restTemplate.postForObject(requesturl + "add.do?user={user}",
		// null, entityClz, uriVariables);
		return restTemplate.postForObject(requesturl, null, String.class, uriVariables);
	}

	public String postRestDataSave(String requesturl, Object... uriVariables) {
		return restTemplate.postForObject(requesturl, null, String.class, uriVariables);
	}

	public String postRestDataSave(String requesturl, String requestJson) {
		HttpHeaders headers = new HttpHeaders();
		MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
		headers.setContentType(type);
		HttpEntity<String> entity = new HttpEntity<String>(requestJson, headers);
		return restTemplate.postForObject(requesturl, entity, String.class);
	}

	public boolean putRestDataUpdate(String requesturl, Object... entityData) {
		try {
			restTemplate.put(requesturl, entityData);
		} catch (RestClientException e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}

	public boolean putRestDataUpdate(String requesturl, Map uriVariables) {
		try {
			restTemplate.put(requesturl, null, uriVariables);
		} catch (RestClientException e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}

	public boolean putRestDataUpdate(String requesturl, Object o) {
		try {
			restTemplate.put(requesturl, o);
		} catch (RestClientException e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}

	public boolean deleteRestDataDelete(String requesturl, Map uriVariables) {
		try {
			restTemplate.delete(requesturl, uriVariables);
		} catch (RestClientException e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}

	public boolean deleteRestDataDelete(String requesturl) {
		try {
			restTemplate.delete(requesturl);
		} catch (RestClientException e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}

	public boolean deleteRestDataDelete(String requesturl, Object... objects) {
		try {
			restTemplate.delete(requesturl, objects);
		} catch (RestClientException e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}

	public String uploadFile(MultipartFile file, String url) throws Exception {
		HttpHeaders headers = new HttpHeaders();
		String tempFileName = UUID.randomUUID() + file.getOriginalFilename();
		String tempFilePath = "" + tempFileName;
		File tempFile = new File(tempFilePath);
		FileUtils.copyInputStreamToFile(file.getInputStream(), tempFile);
		try {
			FileSystemResource fileSystemResource = new FileSystemResource(tempFilePath);
			MediaType type = MediaType.parseMediaType("multipart/form-data");
			headers.setContentType(type);
			String cd = "filename=\"" + file.getOriginalFilename() + "\"";
			headers.add("Content-Disposition", cd);
			MultiValueMap<String, Object> form = new LinkedMultiValueMap<String, Object>();
			form.add("file", fileSystemResource);
			HttpEntity<MultiValueMap<String, Object>> files = new HttpEntity<>(form, headers);
			ResponseEntity<String> responseEntity = null;
			responseEntity = restTemplate.postForEntity(url, files, String.class);
			return responseEntity.getBody();
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		} finally {
			tempFile.delete();
		}
	}

	public String uploadFileNew(MultipartFile file, String url) throws Exception {
		HttpHeaders headers = new HttpHeaders();
		String tempFileName = UUID.randomUUID() + file.getOriginalFilename();
		String tempFilePath = "" + tempFileName;
		File tempFile = new File(tempFilePath);
		FileUtils.copyInputStreamToFile(file.getInputStream(), tempFile);
		try {
			RestTemplate rest = new RestTemplate();
			FileSystemResource resource = new FileSystemResource(tempFile);
			MultiValueMap<String, Object> param = new LinkedMultiValueMap<>();
			param.add("file", resource);
			// param.add("fileName", "test.txt");
			String string = rest.postForObject(url, param, String.class);
			return string;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		} finally {
			tempFile.delete();
		}
	}
}